package com.breaktian.assemble.livedatabus;

import android.arch.lifecycle.ExternalLiveData;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.Observer;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;

import java.util.HashMap;
import java.util.Map;

class BusLiveData<T> extends ExternalLiveData<T> implements ISubscribe<T> {

    private class PostValueTask implements Runnable {
        private Object newValue;

        public PostValueTask(@NonNull Object newValue) {
            this.newValue = newValue;
        }

        @Override
        public void run() {
            setValue((T) newValue);
        }
    }

    @NonNull
    private final String key;
    private Map<Observer, Observer> observerMap = new HashMap<>();
    private Handler mainHandler = new Handler(Looper.getMainLooper());


    BusLiveData(String key) {
        this.key = key;
    }


    @Override
    public void send(T value) {
        mainHandler.post(new PostValueTask(value));
    }

    @Override
    public void sendDelay(T value, long delay) {
        mainHandler.postDelayed(new PostValueTask(value), delay);
    }


    @Override
    public void subscribe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        super.observe(owner, observer);
    }

    @Override
    public void subscribeSticky(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        super.observeSticky(owner, observer);
    }

    @Override
    public void subscribeForever(@NonNull Observer<T> observer) {
        if (!observerMap.containsKey(observer)) {
            observerMap.put(observer, new ObserverWrapper(observer));
        }
        super.observeForever(observerMap.get(observer));
    }

    @Override
    public void subscribeStickyForever(@NonNull Observer<T> observer) {
        super.observeForever(observer);
    }

    @Override
    public void removeSubscriber(@NonNull Observer<T> observer) {
        Observer realObserver = null;
        if (observerMap.containsKey(observer)) {
            realObserver = observerMap.remove(observer);
        } else {
            realObserver = observer;
        }
        super.removeObserver(realObserver);
        if (!hasObservers()) {
            LiveDataBus.getDefault().bus.remove(key);
        }
    }
}